
frappe.views.QueryReport = class QueryReport extends frappe.views.QueryReport{
	setup_report_wrapper() {
		if (this.$report) return;

		// Remove border from
		$(".page-head-content").removeClass("border-bottom");

		let page_form = this.page.main.find(".page-form");
		this.$status = $(`<div class="form-message text-muted small"></div>`)
			.hide()
			.insertAfter(page_form);

		this.$summary = $(`<div class="report-summary"></div>`).hide().appendTo(this.page.main);

		this.$chart = $('<div class="chart-wrapper">').hide().appendTo(this.page.main);
		// 增加echarts
		this.$echarts = $('<div style="height:600px;width:100%" class="echarts-wrapper" id="echarts">').hide().appendTo(this.page.main);

		this.$loading = $(this.message_div("")).hide().appendTo(this.page.main);
		this.$report = $('<div class="report-wrapper">').appendTo(this.page.main);
		this.$message = $(this.message_div("")).hide().appendTo(this.page.main);

	}
	setup_filters() {
		this.clear_filters();
		const { filters = [] } = this.report_settings;

		let filter_area = this.page.page_form;
		// 构建filters时先隐藏echarts，避免其他报表的数据影响
		if(this.$echarts) {
			this.$echarts.hide()
		}
		this.filters = filters
			.map((df) => {
				if (df.fieldtype === "Break") return;

				let f = this.page.add_field(df, filter_area);

				if (df.default) {
					f.set_input(df.default);
				}

				if (df.get_query) f.get_query = df.get_query;
				if (df.on_change) f.on_change = df.on_change;

				df.onchange = () => {
					this.refresh_filters_dependency();

					let current_filters = this.get_filter_values();
					if (
						this.previous_filters &&
						JSON.stringify(this.previous_filters) === JSON.stringify(current_filters)
					) {
						// filter values have not changed
						return;
					}

					// clear previous_filters after 10 seconds, to allow refresh for new data
					this.previous_filters = current_filters;
					setTimeout(() => (this.previous_filters = null), 10000);

					if (f.on_change) {
						f.on_change(this);
					} else {
						if (this.prepared_report) {
							this.reset_report_view();
						} else if (!this._no_refresh) {
							// filters变化的时候应当先隐藏echarts，避免无数据时更新
							if(this.$echarts) {
								this.$echarts.hide()
							}
							this.refresh(true);
						}
					}
				};

				f = Object.assign(f, df);

				return f;
			})
			.filter(Boolean);

		this.refresh_filters_dependency();
		if (this.filters.length === 0) {
			// hide page form if no filters
			this.page.hide_form();
		} else {
			this.page.show_form();
		}
	}
	render_chart(options) {
		this.$echarts.show()
		// 先判断是否已经有echarts实例，如果有，则不再init
		let exsit_echart = echarts.getInstanceByDom(this.$echarts[0])
		if(!exsit_echart) {
			this.echarts = echarts.init(this.$echarts[0], 'light')
		}
		
		set_report_chart(options,this.$echarts[0])
	}
}

function set_report_chart(chart_options,element) {
	if (chart_options.data.labels.length == 0) {
		element.style.$display = 'none'
	}
	let myChart
	let exist_chart =  echarts.getInstanceByDom(element)
	if (exist_chart) {
		exist_chart.clear()
		myChart = exist_chart
	} else {
		myChart = echarts.init(element, 'light');
	}
	
	let echartsOption = {}

	if (chart_options.type == 'donut') {
		echartsOption.tooltip = {
			trigger: 'item'
		}
		echartsOption.legend = {
			top: '5%',
			left: 'center'
		}
		let data = chart_options.data.labels.map((item, index) => {
			return {
				name: __(item),
				value: chart_options.data.datasets[0].values[index]
			}
		})
		echartsOption.series = [
			{
				type: 'pie',
				radius: ['40%', '70%'],
				avoidLabelOverlap: false,
				itemStyle: {
					borderRadius: 10,
					borderColor: '#fff',
					borderWidth: 2
				},
				label: {
					show: false,
					position: 'center'
				},
				emphasis: {
					label: {
						show: true,
						fontSize: 40,
						fontWeight: 'bold'
					}
				},
				labelLine: {
					show: false
				},
				data: data
			}
		]

	} else if (chart_options.type == 'percentage') {
		echartsOption.tooltip = {
			trigger: 'item'
		}
		echartsOption.legend = {
			top: '5%',
			left: 'center'
		}
		let data = chart_options.data.labels.map((item, index) => {
			let sum = 0
			chart_options.data.datasets.forEach(item => {
				sum += item.values[index]
			})
			return {
				name: __(item),
				value: sum
			}
		})
		echartsOption.series = [
			{
				type: 'pie',
				radius: ['40%', '70%'],
				avoidLabelOverlap: false,
				itemStyle: {
					borderRadius: 10,
					borderColor: '#fff',
					borderWidth: 2
				},
				label: {
					show: false,
					position: 'center'
				},
				emphasis: {
					label: {
						show: true,
						fontSize: 40,
						fontWeight: 'bold'
					}
				},
				labelLine: {
					show: false
				},
				data: data
			}
		]

	} else {
		echartsOption.tooltip = {
			trigger: 'axis',
			axisPointer: {
				type: 'cross',
				animation: false,
				label: {
					backgroundColor: '#ccc',
					borderColor: '#aaa',
					borderWidth: 1,
					shadowBlur: 0,
					shadowOffsetX: 0,
					shadowOffsetY: 0,
					color: '#222'
				}
			},
			formatter: function (params) {
				let res = ``
				params.forEach((item, index) => {
					res += `
					<div class="flex justify-content-between" style="color:${item.color};min-width:200px;">
						<div class="bold">${item.seriesName} :</div>
						<div>${fmt_money(item.value)}</div>
					</div>`;
				});
				return res;
			}
		}

		echartsOption.toolbox = {
			show: true,
			feature: {
				dataView: { show: true, readOnly: false },
				magicType: { show: true, type: ['line', 'bar', 'stack'] },
				restore: { show: true },
				// saveAsImage: { show: true }
				myToggleMarkLine: {
					show: true,
					title: '显示标记',
					icon: 'path://M432.45,595.444c0,2.177-4.661,6.82-11.305,6.82c-6.475,0-11.306-4.567-11.306-6.82s4.852-6.812,11.306-6.812C427.841,588.632,432.452,593.191,432.45,595.444L432.45,595.444z M421.155,589.876c-3.009,0-5.448,2.495-5.448,5.572s2.439,5.572,5.448,5.572c3.01,0,5.449-2.495,5.449-5.572C426.604,592.371,424.165,589.876,421.155,589.876L421.155,589.876z M421.146,591.891c-1.916,0-3.47,1.589-3.47,3.549c0,1.959,1.554,3.548,3.47,3.548s3.469-1.589,3.469-3.548C424.614,593.479,423.062,591.891,421.146,591.891L421.146,591.891zM421.146,591.891',
					onclick: function () {
						var chart = myChart;
						var series = chart.getOption().series;
						series.forEach(function (item) {
							item.markLine.lineStyle.opacity = item.markLine.lineStyle.opacity?0:1;
							item.markPoint.itemStyle.opacity = item.markPoint.itemStyle.opacity?0:1;
						});
						chart.setOption({ series: series });
					}
				},
			}
		}

		echartsOption.xAxis = {
			type: 'category',
			data: chart_options.data.labels,
			axisLabel: {
				rotate: 45, 
				interval: 0,
				showMinLabel: true,
				showMaxLabel: true,
				formatter: function (value, index) {
					var maxLength = 8;
					if (value.length > maxLength) {
						return value.slice(0, maxLength) + '...'; 
					}
					return value;
				}
			}
		}

		echartsOption.yAxis = {
			type: 'value'
		}

		let chart_series = chart_options.data.datasets.map((item) => {
			let chart_type = item.chartType || chart_options.type
			let markLineConfig = {
				lineStyle:{
					opacity:0,
				},
				data: [{ type: 'average', name: __('Average') }]
			}

			const labelOption = {
				show: true,
				rotate: 90,
				formatter: function (params) {
					return params.value === 0 ? '' : params.value.toLocaleString('zh-CN',
						{
							minimumFractionDigits: 2, 
							maximumFractionDigits: 2 
						}
					);
				},
				fontSize: 12,
				color: '#FFFFFF',
				rich: {
					name: {}
				}
			};
			var emphasisStyle = {
				itemStyle: {
					shadowBlur: 10,
					shadowColor: 'rgba(0,0,0,0.3)',
				},
				focus: 'series'
			};

			return {
				name: item.name,
				type: chart_type,
				smooth: true,
				barGap: 0,
				label: item.values.length < 10 ? labelOption : {},
				data: item.values,
				showBackground: true,
				emphasis: emphasisStyle,
				markPoint: {
					itemStyle:{
						opacity:0,
					},
					data: [
						{ type: 'max', name: __('Maximum') },
						{ type: 'min', name: __('Minimum') }
					]
				},
				markLine: markLineConfig,
				animationDelay: function (idx) {
					return idx * 10;
				},
				animationEasing: 'elasticOut',
				animationDelayUpdate: function (idx) {
					return idx * 5;
				},
				backgroundStyle: {
					color: 'rgba(220, 220, 220, 0.2)'
				}
			}
		})

		echartsOption.series = chart_series
		echartsOption.legend = {
			orient: 'vertical',
			right: 10,
			top: 'center'
		}
		echartsOption.dataZoom = [
			{
				type: 'slider', 
				xAxisIndex: 0,
				start: 0,
				end: 100
			},
			{
				type: 'inside',
				xAxisIndex: 0,
				start: 0,
				end: 100
			}
		]
	}
	echartsOption && myChart.setOption(echartsOption);
	window.addEventListener('resize', function () {
		myChart.resize();
	});
}

export { set_report_chart }